# coding: utf-8
# File   :  deepseek_control
# Author :  wangsheng
# @Time  :  2025/5/28 上午10:43
from openai import OpenAI
from utils.yaml_control import YamlReader
import json
import os
import openpyxl
from openpyxl.styles import Font, Alignment, PatternFill
from openpyxl.utils import get_column_letter


def testcase_ai(user_prompt: str):
    client = OpenAI(
        api_key=YamlReader.read().get("api_key"),
        base_url="https://api.deepseek.com",
    )

    system_prompt = """
    作为专业的软件测试工程师，请根据用户提供的功能需求或场景描述，生成结构化的测试用例，。输出必须为JSON格式，尽可能生成所有场景下的测试用例，包含以下基本要素：
    1、case_id：采用项目缩写_模块_序号格式
    2、module：明确功能模块
    2、case_name：明确描述测试目的
    3、priority：高/中/低三级划分
    4、test_type：标注测试方法
    5、preconditions：列出执行前提
    6、steps：使用明确的动作动词，序号标出
    7、expected_result：验证标准
    """

    messages = [{"role": "system", "content": system_prompt},
                {"role": "user", "content": user_prompt}]
    print("---------------TestCase由DeepSeek正在生成中，请稍等--------------------")
    try:
        response = client.chat.completions.create(
            model="deepseek-chat",
            messages=messages,
            response_format={
                'type': 'json_object'
            },
            temperature=0.3,
            presence_penalty=0.5,
            top_p=0.9,
            stream=False
        )
        return json.loads(response.choices[0].message.content)
    except Exception as e:
        import traceback
        error_msg = f"""
            错误类型: {type(e).__name__}
            错误详情: {str(e)}
            调用堆栈: {traceback.format_exc()}  # 获取完整调用栈
            """
        print(error_msg)


def write_testcases_to_excel(_data, output_file="../out_files/test_cases.xlsx"):
    """
    将测试用例写入Excel文件（如果文件已存在，则追加内容）

    Args:
        _data (dict): 测试用例数据，格式如 {'test_cases': [用例1, 用例2...]}
        output_file (str): 输出文件路径
    """
    # 检查文件是否存在
    try :
        file_exists = os.path.exists(output_file)

        if file_exists:
            # 追加模式：加载现有工作簿
            wb = openpyxl.load_workbook(output_file)
            if "测试用例" in wb.sheetnames:
                ws = wb["测试用例"]
                start_row = ws.max_row + 1  # 从最后一行之后开始追加
            else:
                ws = wb.create_sheet("测试用例")
                start_row = 1
        else:
            # 新建模式
            wb = openpyxl.Workbook()
            ws = wb.active
            ws.title = "测试用例"
            start_row = 1

        # 如果是新文件或新Sheet，写入表头
        if start_row == 1:
            headers = ["用例ID", "模块", "用例名称", "优先级", "测试类型", "前置条件", "测试步骤", "预期结果"]
            ws.append(headers)

            # 设置表头样式
            header_font = Font(bold=True, color="FFFFFF")
            header_fill = PatternFill(start_color="4F81BD", end_color="4F81BD", fill_type="solid")
            for col in range(1, len(headers) + 1):
                cell = ws.cell(row=1, column=col)
                cell.font = header_font
                cell.fill = header_fill
                cell.alignment = Alignment(horizontal="center")

        # 写入测试用例数据（从 start_row 开始）
        for case in _data["test_cases"]:
            # 处理列表类型的字段
            preconditions = case.get("preconditions", [])
            steps = case.get("steps", [])

            preconditions_str = "\n".join(preconditions) if isinstance(preconditions, list) else preconditions
            steps_str = "\n".join(steps) if isinstance(steps, list) else steps

            row = [
                case["case_id"],
                case["module"],
                case["case_name"],
                case["priority"],
                case["test_type"],
                preconditions_str,
                steps_str,
                case["expected_result"]
            ]
            ws.append(row)

        # 设置自动换行和列宽（仅对新写入的行生效）
        for row in ws.iter_rows(min_row=start_row):
            for cell in row:
                cell.alignment = Alignment(wrap_text=True, vertical="top")

        # 调整所有列的宽度（避免旧数据列宽不合适）
        for col in ws.columns:
            max_length = max(
                len(str(cell.value)) if cell.value else 0
                for cell in col
            )
            adjusted_width = min(max_length + 2, 50)  # 限制最大50字符
            ws.column_dimensions[get_column_letter(col[0].column)].width = adjusted_width

        # 保存文件
        wb.save(output_file)
        print(f"测试用例已{'追加到' if file_exists else '写入'} {output_file}")
    except Exception as e:
        import traceback
        error_msg = f"""
            错误类型: {type(e).__name__}
            错误详情: {str(e)}
            调用堆栈: {traceback.format_exc()}
            """
        print(error_msg)


if __name__ == '__main__':
    prompt = """
    项目名称：电池溯源平台
    模块：首页
    功能：注册
    参数：用户名（最长20位，仅支持大小写字母和下划线），密码 （最长20位，支持数字字母符号，需包含大小写），邮箱，邮箱验证码
    逻辑：
    """
    data = testcase_ai(prompt)

    print(data)
    print(type(data))

    # data = {'test_cases': [{'case_id': 'BTP_Home_01', 'case_name': '验证用户名输入规则-仅支持大小写字母和下划线', 'priority': '高', 'test_type': '功能测试', 'preconditions': '用户进入注册页面', 'steps': ["1. 在用户名输入框中输入'Test_User'", '2. 输入有效的密码、邮箱和验证码', '3. 点击注册按钮'], 'expected_result': '注册成功，用户被重定向到首页或登录页面'}, {'case_id': 'BTP_Home_02', 'case_name': '验证用户名输入规则-包含非法字符', 'priority': '高', 'test_type': '功能测试', 'preconditions': '用户进入注册页面', 'steps': ["1. 在用户名输入框中输入'Test@User'", '2. 输入有效的密码、邮箱和验证码', '3. 点击注册按钮'], 'expected_result': '注册失败，提示用户名仅支持大小写字母和下划线'}, {'case_id': 'BTP_Home_03', 'case_name': '验证用户名长度限制', 'priority': '中', 'test_type': '功能测试', 'preconditions': '用户进入注册页面', 'steps': ["1. 在用户名输入框中输入超过20位的字符'Test_User_Test_User_Test'", '2. 输入有效的密码、邮箱和验证码', '3. 点击注册按钮'], 'expected_result': '注册失败，提示用户名长度不能超过20位'}, {'case_id': 'BTP_Home_04', 'case_name': '验证密码复杂度要求', 'priority': '高', 'test_type': '功能测试', 'preconditions': '用户进入注册页面', 'steps': ["1. 在密码输入框中输入符合要求的密码'Test123!'", '2. 输入有效的用户名、邮箱和验证码', '3. 点击注册按钮'], 'expected_result': '注册成功，用户被重定向到首页或登录页面'}, {'case_id': 'BTP_Home_05', 'case_name': '验证密码复杂度不足', 'priority': '高', 'test_type': '功能测试', 'preconditions': '用户进入注册页面', 'steps': ["1. 在密码输入框中输入不符合要求的密码'test123'", '2. 输入有效的用户名、邮箱和验证码', '3. 点击注册按钮'], 'expected_result': '注册失败，提示密码需包含大小写字母和符号'}, {'case_id': 'BTP_Home_06', 'case_name': '验证邮箱格式', 'priority': '高', 'test_type': '功能测试', 'preconditions': '用户进入注册页面', 'steps': ["1. 在邮箱输入框中输入无效的邮箱格式'testuser'", '2. 输入有效的用户名、密码和验证码', '3. 点击注册按钮'], 'expected_result': '注册失败，提示邮箱格式不正确'}, {'case_id': 'BTP_Home_07', 'case_name': '验证邮箱验证码的正确性', 'priority': '高', 'test_type': '功能测试', 'preconditions': '用户进入注册页面，并获取了邮箱验证码', 'steps': ["1. 在邮箱验证码输入框中输入错误的验证码'0000'", '2. 输入有效的用户名、密码和邮箱', '3. 点击注册按钮'], 'expected_result': '注册失败，提示验证码错误'}]}
    # test_cases = data['test_cases']
    # for case in test_cases:
    #     print(f"用例ID: {case['case_id']}")
    #     print(f"用例名称: {case['case_name']}")
    #     print(f"优先级: {case['priority']}")
    #     print("测试步骤：")
    #     for step in case['steps']:
    #         print(step)
    #     print("------")
